﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using System.ComponentModel;
using System.Reflection;
namespace STRobot
{
    interface IToString
    {
        String GetString();
    }


    public enum AttackMode //模式
    {
        [Description("yuk!")] a_auto, //普通攻击，战士模式
        a_remote, //远程攻击模式，需要设置不同的远程技能
        a_stopwar, //观战模式，仅找怪或者随机，由宠物
        a_ai_auto, //AI近战模式，仅找怪或者随机AI攻击
        a_ai_remote //AI远程模式，仅找怪或者随机AI攻击
    };

    public struct Point : IToString
    {
        public int x;
        public int y;
        public Point(int a,int b)
        {
            x = a; y = b; 
        }
        public String GetString()
        {
            //return String.Format("\n{{\"x\":{0},\"y\":{1}}}", x, y);
            return JsonConvert.SerializeObject(this);
        }
    }
    public class Bigmonster : IToString
    {
        public int type; //是指定怪还是排除怪
        public String name { get; set; }
        public int tid { get; set; }
        public int level { get; set; }
        public String GetString()
        {
            return String.Format("\n{{\"name\":\"{0}\",\"tid\":{1},\"level\":{2}}}", name, tid, level);
        }
    }

    public class Skill : IToString
    {
        public String name { get; set; }
        public double cd { get; set; }
        public int key { get; set; }
        public bool pcd { get; set; } //公共CD是否触发
        public bool select { get; set; } //此技能是否需要鼠标点怪 
        public String GetString()
        {
            return String.Format("\n{{\"name\":\"{0}\",\"cd\":{1},\"key\":{2},\"pcd\":{3},\"select\":{5}}}", name, cd, key, pcd,select);
        }
    }

    public class UiClick : IToString  //UI点击抽象 可由按键，UI界面  NPC触发出来
    {
        public int key;
        public String uiname;
        public String npc;
        public List<Point> click;
        public String GetString()
        {
            var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
            var str = JsonConvert.SerializeObject(this, Formatting.None, jsonSetting);
            return str;
        }
    }

    public struct AoeTrigger //可以扩展支持更多种情况
    {
        public int range; //单位范围内
        public int number;  //有多少个怪 时触发
        public int outnumber;//额外的怪
        public bool outer; //范围外时触发
    }
    public struct Useskill  //定义需要使用的技能
    {
        public AoeTrigger aoetrigger;        //群攻时判断数量
        public Skill single;   //单体技能
        public Skill aoe;  //群攻技能
        public Skill home;     //回城技能
        public Skill debuff;    //debuff技能 上毒，火墙
        public Skill random; //随机技能
    }

    public struct Guajipoint   //挂机的地图信息设置
    {
        public String showname; //地图名
        public int flushtime; //刷新时间
        public int idletime;//停留最长时间
        public int timeout; //超时次数 -1 不进此挂机地图，0可用，大于0为使用随机巡巡逻，超过则换图
        public List<Point> points; //循环路图点
    }

    public struct JumpTargetpoint  //需要单独添加的跳转点，比如找NPC点击进入的地图之类
    {
        public String showname; //目标地图名，标识用
        public String targetname; //目标地图,跳转后显示的地图名，用来确定是否跳转成功
        public String npc; //对应NPC
        public String uiname; //成功对话时出现的对话框
        public List<UiClick> talk; //对话流程
    }

    public struct Jumppoint
    {
        public String starmapname; //初始地图,一般为主城安全区
        public List<JumpTargetpoint> targetmap;//目标地图
    }

    public struct Petinfo : IToString  //游戏中需要召唤的宠物，比道士道士宝宝和捡物宝宝
    {
        public int tid;//宠物id
        public String name; //宠物名称
        public int enable; //是否启动
        public List<UiClick> call; //召唤方式
        public String GetString()
        {
            String str = String.Format("\n{\n\"tid\":{0},\"name\":\"{1}\",\"enable\":{2},\"call\":[",tid,name,enable);
            for (int i = 0; i < call.Count; i++)
            {
                str += call[i].GetString();
                if (i < call.Count)
                {
                    str += ",";
                }
            }
            str += "]\n}";
            return str;
        }
    }

    //public struct Home
    //{
    //    public String name; //
    //    public String into; //skill 
    //}
    public class Config
    {
        public static string GetDescription(AttackMode value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes =
                  (DescriptionAttribute[])fi.GetCustomAttributes(
                  typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
        }

        private static Config instance_ = null;
        private bool  configisok_ = false;
        private Config() {

        }
        public void InitFromFile()
        {
            try
            {
                petinfo = new List<Petinfo>();
                jumppoints = new List<Jumppoint>();
                guajipoint = new List<Guajipoint>();
                bigmonsterlist = new List<Bigmonster>();

                if (File.Exists(@"stconfig.json"))
                {
                    using (var file = File.OpenText(@"stconfig.json"))
                    {
                        JsonTextReader reader = new JsonTextReader(file);
                        var str = file.ReadToEnd();
                        instance_ = JsonConvert.DeserializeObject<Config>(str);
                    }
                }
                
            }
            catch (Exception)
            {


            }
               
        }
        public void SaveToFile()
        {
            var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
            var str = JsonConvert.SerializeObject(this, Formatting.Indented, jsonSetting);
            File.WriteAllText(@"stconfig.json", str);
        }
        public static Config Get()
        {
            if (instance_ == null)
            {
                instance_ = new Config();
                //instance_.InitFromFile();
            }
            return instance_;
        }
        public String servername;
        public String rolename;
        public int levelpriority; 
        public int monsterlevel; //指定怪物列表中X级别以上的才打。
        public int attackdistance;
        public int attackmode; //攻击模式，1脚本近战攻击  2自带的自动攻击
        public int idletime; //怪死后附近没有时，停留多久，以保证地上的东西捡完了
        public int pickup;//由脚本自己拾取物品 = 1
        public int otherplayer; //是否检查其他玩家，
        public int emptyaround;//身边有没有怪堵住，如果有设置的数量，则直接把这些怪当目标处理掉

        public List<Petinfo> petinfo = new List<Petinfo>();
        public List<String> home = new List<string>(); //所有主城名,使用回城后让程序知道已经成功回城
        public List<Jumppoint> jumppoints = new List<Jumppoint>(); //记录所有主城对应的跳转点
        public List<Guajipoint> guajipoint = new List<Guajipoint>(); //挂机点信息
        public List<Bigmonster> bigmonsterlist = new List<Bigmonster>();  //需要攻击的怪物列表
        public List<String> notpickupitem = new List<string>();  //排除不拾取的物品
        public List<UiClick> tankuangclose = new List<UiClick>();     //检查一些弹窗的设置
        public Useskill useskill = new Useskill();  //设置可用的技能信息
        public int autohuishou = 0; //是否开启回收功能，有些服有自动回收时不需要
        public List<UiClick> huishou = new List<UiClick>(); //自动回收时的一系列UI操作
        public List<UiClick> autoswitch = new List<UiClick>(); //游戏自带的自动战斗的开关方式
    }

}
